#include "connect_pool.h"
#include <iostream>
#include <cstring>
#include <string_view> // 引入 string_view
// #include "../protocol/protocol.h"
// #include "../../db_binary_serialization.h"
#include "../utils/socket_utils.hpp"
// 全局变量定义 - 控制服务器运行状态
bool is_running = true;

// 构造函数实现
ConnectionPool::ConnectionPool() : config(Config::getInstance())
{
    max_connections = config.GetValue<uint16_t>("max_connections", 10);
    // 初始化工作线程，数量等于最大连接数
    for (int i = 0; i < max_connections; ++i)
    {
        // 向工作线程容器中添加新线程，线程执行worker()函数
        worker_threads.emplace_back(&ConnectionPool::worker, this);
    }
}

// 析构函数实现
ConnectionPool::~ConnectionPool()
{
    // 设置运行标志为false，通知所有工作线程退出
    is_running = false;

    // 唤醒所有等待的工作线程
    cv.notify_all();

    // 等待所有工作线程完成并回收资源
    for (auto &thread : worker_threads)
    {
        // 检查线程是否可连接（即是否还在运行）
        if (thread.joinable())
        {
            // 等待线程结束
            thread.join();
        }
    }
}

inline void safe_strncpy(char *dest, const std::string &src, size_t dest_size)
{
    if (dest_size == 0)
        return;
    size_t len_to_copy = (std::min)(src.length(), dest_size - 1);
    memcpy(dest, src.c_str(), len_to_copy);
    dest[len_to_copy] = '\0';
}

#ifdef _WIN32
bool ConnectionPool::add_connection(SOCKET client_socket)
{
    // 使用lock_guard自动管理互斥锁，确保线程安全
    std::lock_guard<std::mutex> lock(mtx);

    // 检查连接池是否已满
    if (connections.size() >= max_connections)
    {
        return false; // 连接池已满，返回失败
    }

    // 将新连接添加到队列
    connections.push(client_socket);

    // 通知一个等待的工作线程有新连接可用
    cv.notify_one();

    return true; // 连接添加成功
}

void ConnectionPool::handle_connection(socket_t client_socket)
{
    // 获取客户端地址信息 (这部分不变)
    struct sockaddr_in client_addr;
    int client_len = sizeof(client_addr);
    getpeername(client_socket, (struct sockaddr *)&client_addr, &client_len);
    char client_ip_str[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &(client_addr.sin_addr), client_ip_str, INET_ADDRSTRLEN);
    std::string client_ip = client_ip_str;
    int client_port = ntohs(client_addr.sin_port);
    if (config.GetValue<std::string>("host", "127.0.0.1") != "0.0.0.0" && client_ip != "127.0.0.1")
    {
        std::cout << "not allow ip: " << client_ip << " to connect" << std::endl;
        close_socket(client_socket);
        return;
    }
    std::cout << "New connection from " << client_ip << ":" << client_port << std::endl;
    bool connection_active = true;
    while (is_running && connection_active) // 只要服务器在运行，就保持连接
    {
        // --- 1. 使用 select 来等待数据，并设置超时 ---
        fd_set read_fds;
        FD_ZERO(&read_fds);
        FD_SET(client_socket, &read_fds);

        // 设置1秒的超时
        struct timeval timeout;
        timeout.tv_sec = 1;
        timeout.tv_usec = 0;

        // select 会阻塞，直到套接字可读，或超时，或出错
        int activity = select(client_socket + 1, &read_fds, NULL, NULL, &timeout);

        if (activity < 0)
        { // select 出错
            std::cerr << "select() error: " << WSAGetLastError() << std::endl;
            break;
        }

        if (activity == 0)
        {
            // 超时，没有数据可读。这是一个检查 is_running 的好机会。
            continue; // 继续下一次 while 循环，检查 is_running
        }
        // 1. 接收消息头
        MessageHeader header;
        if (!recv_all(client_socket, &header, sizeof(MessageHeader), client_ip, client_port))
        {
            connection_active = false;
            continue;
        }
        // 2. 解析消息头
        header.length = ntohl(header.length);
        // 3. 准备缓冲区并接收消息体
        std::vector<char> body_buffer(header.length);
        if (header.length > 0)
        {
            if (!recv_all(client_socket, body_buffer.data(), header.length, client_ip, client_port))
            {
                connection_active = false;
                continue; // 跳出并结束循环
            }
        }

        // 4. 根据消息类型进行分发处理
        switch (header.type)
        {
        case OperationType::LOGIN_REQUEST:
        {
            LoginResponse resp;
            if (header.length == sizeof(LoginRequest))
            {
                LoginRequest *req = (LoginRequest *)body_buffer.data();
                std::cout << "Received login request for user: " << req->username << std::endl;

                if (std::string_view(req->username) == config.GetValue<std::string>("user", "root") && std::string_view(req->password) == config.GetValue<std::string>("password", "root"))
                {
                    std::cout << "Login successful." << std::endl;
                    resp.success = true;
                    safe_strncpy(resp.message, "Login successful!", sizeof(resp.message));
                }
                else
                {
                    std::cout << "Login failed." << std::endl;
                    resp.success = false;
                    safe_strncpy(resp.message, "Invalid username or password.", sizeof(resp.message));
                }

                if (send(client_socket, (const char *)&resp, sizeof(LoginResponse), 0) == SOCKET_ERROR_VAL)
                {
                    // 发送失败，可能连接已断开
                    connection_active = false;
                }
            }
            else
            {
                std::cerr << "Invalid packet size for LOGIN_REQUEST." << std::endl;
                resp.success = false;
                safe_strncpy(resp.message, "Invalid packet size.", sizeof(resp.message));
                resp.message[sizeof(resp.message) - 1] = '\0';
                if (send(client_socket, (const char *)&resp, sizeof(LoginResponse), 0) == SOCKET_ERROR_VAL)
                {
                    std::cerr << " server send fail: " << WSAGetLastError() << std::endl;
                    connection_active = false;
                }
            }
            break;
        }
        case OperationType::SQL_REQUEST:
        {
            try
            {

                std::string sql(body_buffer.data(), header.length);
                std::cout << "Received SQL request: " << sql << std::endl;
                if (sql == "exit")
                {
                    std::cout << "Received exit command." << std::endl;
                    connection_active = false; // 标记连接为非活动，以退出循环
                    break;
                }

                QueryResult result = db.execute_sql(sql);
                // Serializer s;
                // s << result;
                json j = toJson(result);
                std::string s = j.dump();
                std::cout << "result: " << j.dump(4) << std::endl;
                if (!send_packet(client_socket, OperationType::SQL_RESPONSE, s.c_str(), static_cast<uint32_t>(s.size())))
                {
                    std::cerr << " server send fail: " << WSAGetLastError() << std::endl;
                    connection_active = false;
                }
            }
            catch (const std::exception &e)
            {
                std::cerr << "SQL request failed: " << e.what() << std::endl;
                connection_active = false;
            }
            break;
        }
        default:
        {
            std::cerr << "Received unknown message type: " << static_cast<int>(header.type) << std::endl;
            connection_active = false;
            break;
        }
        }
    }
    std::cout << "Connection with " << client_ip << ":" << client_port << " closed" << std::endl;
    close_socket(client_socket);
}

// 工作线程函数实现
void ConnectionPool::worker()
{
    // 只要服务器在运行，工作线程就持续工作
    while (is_running)
    {
        // 存储将要处理的客户端套接字
        SOCKET client_socket;

        // 临界区：从连接队列中获取一个连接
        {
            // unique_lock用于管理互斥锁，支持条件变量的等待操作
            std::unique_lock<std::mutex> lock(mtx);

            // 等待条件：队列不为空或服务器停止运行
            // wait()会释放锁并阻塞，直到被通知或超时
            cv.wait(lock, [this]
                    { return !connections.empty() || !is_running; });

            // 如果服务器停止运行，退出循环
            if (!is_running)
                break;

            // 从队列中获取一个客户端套接字
            client_socket = connections.front();
            // 从队列中移除该套接字
            connections.pop();
        }

        // 处理获取到的客户端连接
        handle_connection(client_socket);
    }
}
#elif defined(__linux__)
void ConnectionPool::handle_connection(socket_t client_socket)
{
    // 获取客户端地址信息 (这部分不变)
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    getpeername(client_socket, (struct sockaddr *)&client_addr, &client_len);
    // inet_ntoa 返回的是静态缓冲区指针，最好立即复制
    std::string client_ip = inet_ntoa(client_addr.sin_addr);
    int client_port = ntohs(client_addr.sin_port);
    if (config.GetValue<std::string>("host", "127.0.0.1") != "0.0.0.0" && client_ip != "127.0.0.1")
    {
        std::cout << "not allow ip: " << client_ip << " to connect" << std::endl;
        close_socket(client_socket);
        return;
    }
    std::cout << "New connection from " << client_ip << ":" << client_port << std::endl;

    // 只要服务器在运行，就保持连接
    while (is_running)
    {
        // 1. 接收消息头
        MessageHeader header;
        if (!recv_all(client_socket, &header, sizeof(MessageHeader)))
        {
            // recv_all 内部已经打印了错误信息或连接关闭信息
            break;
        }

        // 2. 解析消息头 (将网络字节序转为主机字节序)
        header.length = ntohl(header.length);

        // 3. 准备缓冲区并接收消息体
        std::vector<char> body_buffer(header.length);
        if (header.length > 0)
        {
            if (!recv_all(client_socket, body_buffer.data(), header.length))
            {
                break;
            }
        }

        // 4. 根据消息类型进行分发处理
        switch (header.type)
        {
        case OperationType::LOGIN_REQUEST:
        {
            LoginResponse resp;
            if (header.length == sizeof(LoginRequest))
            {
                LoginRequest *req = reinterpret_cast<LoginRequest *>(body_buffer.data());
                std::cout << "Received login request for user: " << req->username << std::endl;

                // 假设 USERNAME 和 PASSWORD 是已定义的常量或全局变量
                if (std::string_view(req->username) == config.GetValue<std::string>("user", "root") && std::string_view(req->password) == config.GetValue<std::string>("password", "root"))
                {
                    std::cout << "Login successful." << std::endl;
                    resp.success = true;
                    strncpy(resp.message, "Login successful!", sizeof(resp.message) - 1);
                }
                else
                {
                    std::cout << "Login failed." << std::endl;
                    resp.success = false;
                    strncpy(resp.message, "Invalid username or password.", sizeof(resp.message) - 1);
                }
                resp.message[sizeof(resp.message) - 1] = '\0';

                // 直接使用 send 发送固定大小的响应结构体
                if (send(client_socket, (const char *)&resp, sizeof(LoginResponse), 0) == SOCKET_ERROR_VAL)
                {
                    perror("send login response failed");
                }
            }
            else
            {
                std::cerr << "Invalid packet size for LOGIN_REQUEST." << std::endl;
                resp.success = false;
                strncpy(resp.message, "Invalid packet size.", sizeof(resp.message) - 1);
                resp.message[sizeof(resp.message) - 1] = '\0';
                if (send(client_socket, (const char *)&resp, sizeof(LoginResponse), 0) == SOCKET_ERROR_VAL)
                {
                    perror("send login response failed");
                }
            }
            break;
        }

        case OperationType::SQL_REQUEST:
        {
            // 从缓冲区构造 string，确保长度正确
            std::string sql(body_buffer.data(), header.length);
            std::cout << "Received SQL request from " << client_ip << ":" << client_port << ": " << sql << std::endl;

            // 检查退出命令
            if (sql == "exit")
            {
                std::cout << "Client " << client_ip << ":" << client_port << " sent exit command." << std::endl;
                goto end_connection;
            }

            // 假设 db 是一个可访问的数据库实例
            QueryResult result = db.execute_sql(sql);
            json j = toJson(result);
            std::string s = j.dump();
            std::cout << "result: " << j.dump(4) << std::endl;
            if (!send_packet(client_socket, OperationType::SQL_RESPONSE, s.c_str(), static_cast<uint32_t>(s.size())))
            {
                perror("send sql response failed");
                goto end_connection;
            }
            break;
        }

        default:
        {
            std::cerr << "Received unknown message type: " << static_cast<int>(header.type)
                      << " from " << client_ip << ":" << client_port << std::endl;
            // 可以选择断开恶意或错误的连接
            // goto end_connection;
            break;
        }
        }
    }

end_connection:
    std::cout << "Connection with " << client_ip << ":" << client_port << " closed" << std::endl;
    close_socket(client_socket); // 使用跨平台的关闭函数
}

bool ConnectionPool::add_connection(int client_socket)
{
    // 使用lock_guard自动管理互斥锁，确保线程安全
    std::lock_guard<std::mutex> lock(mtx);

    // 检查连接池是否已满
    if (connections.size() >= max_connections)
    {
        return false; // 连接池已满，返回失败
    }

    // 将新连接添加到队列
    connections.push(client_socket);

    // 通知一个等待的工作线程有新连接可用
    cv.notify_one();

    return true; // 连接添加成功
}

// 工作线程函数实现
void ConnectionPool::worker()
{
    // 只要服务器在运行，工作线程就持续工作
    while (is_running)
    {
        // 存储将要处理的客户端套接字
        int client_socket;

        // 临界区：从连接队列中获取一个连接
        {
            // unique_lock用于管理互斥锁，支持条件变量的等待操作
            std::unique_lock<std::mutex> lock(mtx);

            // 等待条件：队列不为空或服务器停止运行
            // wait()会释放锁并阻塞，直到被通知或超时
            cv.wait(lock, [this]
                    { return !connections.empty() || !is_running; });

            // 如果服务器停止运行，退出循环
            if (!is_running)
                break;

            // 从队列中获取一个客户端套接字
            client_socket = connections.front();
            // 从队列中移除该套接字
            connections.pop();
        }

        // 处理获取到的客户端连接
        handle_connection(client_socket);
    }
}
#endif
